export type isReadOnly<T> = (model: T) => boolean;

export interface NumberOption<T> {
  type: 'number-value';
  label: string;
  readOnly?: boolean | isReadOnly<T>;
  format?: (value: number) => string;
}

export interface ValueOption<T, V> {
  type: 'value';
  label: string;
  readOnly?: boolean | isReadOnly<T>;
  format?: (value: V) => string;
}

export interface TimeOption<T, V> {
  type: 'time';
  label: string;
  readOnly?: boolean | isReadOnly<T>;
  format: (value: V) => string;
}

export interface Mapping<V> {
  label: string;
  value: V;
}

export interface BinaryCategoryOption<T> {
  type: 'binary-category';
  label: string;
  readOnly?: boolean | isReadOnly<T>;
  format?: (value: number | boolean) => string;
  mappings: [Mapping<number | boolean>, Mapping<number | boolean>];
}

export interface CategoryOption<T, V> {
  type: 'category';
  label: string;
  readOnly?: boolean | isReadOnly<T>;
  format?: (value: V) => string;
  mappings: Mapping<V>[] | Promise<Mapping<V>[]>;
}

export type Options<T> = {
  [P in keyof T]?:
    | NumberOption<T>
    | ValueOption<T, T[P]>
    | TimeOption<T, T[P]>
    | BinaryCategoryOption<T>
    | CategoryOption<T, T[P]>;
};

export interface Actions {
  select?: boolean;
  insert?: boolean;
  update?: boolean;
  delete?: boolean;
  batchDelete?: boolean;
  otherForTable?: boolean;
  otherForRow?: boolean;
}
